<template>
  <div>
    <div class="search-box">
      <el-date-picker
        v-model="dateList"
        type="daterange"
        value-format="yyyy-MM-dd"
        range-separator="至"
        start-placeholder="开始日期"
        end-placeholder="结束日期"
      >
      </el-date-picker>
      <el-select
        v-model="indicatrix"
        placeholder="请选择"
        style="margin-left: 16px"
      >
        <el-option
          v-for="item in options"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        >
        </el-option>
      </el-select>
      <el-button type="primary" style="margin-left: 16px" @click="getChartData"
        >查询</el-button
      >
    </div>
    <template v-if="hospitalList.length">
      <div id="map" style="position: absolute; left: 0; top: 0;width: 100%; height: calc(100vh - 60px)"></div>
      <div id="legend" style="display: flex;height: 200px; position: absolute; bottom: 10px; right: 10px; background-color: white; padding: 10px;">
        <div id="legend-1" style="height: 180px;"></div>
        <div id="legend-2" class="length-box2"></div>
      </div>
    </template>
  </div>
</template>
<script>
import {
  queryLegend,
  queryHospitalIndex,
  queryHospital,
} from "@/api/atlas/index";
import 'ol/ol.css'
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import ImageLayer from 'ol/layer/Image.js';
import { fromLonLat } from 'ol/proj'
import XYZ from 'ol/source/XYZ.js';
import ImageCanvas from 'ol/source/ImageCanvas.js';
import VectorSource from 'ol/source/Vector.js';
import VectorLayer from 'ol/layer/Vector.js';
import {Style,Fill,Stroke } from 'ol/style';
import GeoJSON from 'ol/format/GeoJSON.js';
import kriging from 'kriging.js';
import taiyuan from './taiyuan.json'
import { apiUrl } from '@/config/setting'

export default {
  data() {
    return {
      map: null,
      sourcePoint: null,
      dateList: [],
      indicatrix: "DNT", // DNT DRT  DPT
      options: [
        {
          value: "DNT",
          label: "DNT分布图",
        },
        {
          value: "DRT",
          label: "DRT分布图",
        },
        {
          value: "DPT",
          label: "DPT分布图",
        },
      ],
      hospitalList: [],
      levelList: [],
      hospitaColorlList: [],
      bianjie: [],
    };
  },
  mounted() {
    const bianjie = taiyuan.features[0].geometry.coordinates[0];
    this.bianjie = [...bianjie];
    setTimeout(() => {
        this.initMap();
        this.drawKriging();
    }, 1500);
  },
  created() {
    this.getColorData();
    this.getHospitalLocation();
  },
  methods: {
    getChartData() {
      this.map = null;
      this.hospitalList = [];
      this.levelList = [];
      this.hospitaColorlList = [];
      setTimeout(()=> {
        this.getColorData();
        this.getHospitalLocation();
      })
      setTimeout(() => {
        this.initMap();
        // this.drawKriging();
      }, 1500);
    },
    // 根据指标查询图例信息
    getColorData() {
      const param = {
        name: this.indicatrix,
      };
      queryLegend(param).then((res) => {
        this.levelList = [...res.data];
      });
    },
    // 查询当前医院,并且返回经纬度
    getHospitalLocation() {
      const param = {
        startDate: "",
        endDate: "",
      };
      if (this.dateList && this.dateList.length) {
        param.startDate = this.dateList[0];
        param.endDate = this.dateList[1];
      }
      queryHospital(param).then((res) => {
        this.hospitalList = [...res.data];
        this.hospitaColorlList = [];
        for (let i = 0; i < res.data.length; i++) {
          this.getHospitalData(res.data[i].deptName);
        }
      });
    },
    // 查询当前医院的指标信息
    getHospitalData(hospitalName) {
      const param = {
        indicatrix: this.indicatrix,
        hospitalName,
      };
      queryHospitalIndex(param).then((res) => {
        let data = [...res.data];
        let arr = [...this.hospitaColorlList];
        for (let i = 0; i < data.length; i++) {
          const hos = data[i]; // 每个医院的数据为list, 所以遍历(估计是怕某个医院有两个地方)
          for (let k = 0; k < this.levelList.length; k++) {
            const level = this.levelList[k]; // 某个等级
            if (
              hos.indicatrixValue - 0 > level.lower - 0 &&
              hos.indicatrixValue - 0 < level.upper - 0
            ) {
              hos.color = level.color;
            }
            if (hos.indicatrixValue - 0 == 0) {
              hos.color = 'rgba(0,0,0,0)';
            }
          }
          if(hos.indicatrixValue) {
            arr.push(hos);
          }
        }
        this.hospitaColorlList = [...arr];
      });
    },
    initMap() {
      // 中国地图的边界坐标（这些值可能需要根据实际情况进行调整）
      // const chinaExtent = [73.45100463562233, 3.860833671999949, 135.16100463562233, 53.53194444444445];
      // 初始化地图
      this.map = new Map({
        target: 'map', // 地图容器的id
        layers: [
          new TileLayer({
            // source: new OSM({
            //   projection: 'EPSG:3857'
            // }), // 开源地图提供者
            source: new XYZ({
              // 设置切片数据的URL模板，{z}表示缩放级别，{x}和{y}表示切片坐标
              // url: 'http://101.201.226.21/gaode/{z}/{x}/{y}.png',
              url: apiUrl + '/profile/tiles_img_gaode_china_large/{z}/{x}/{y}.png',
              // 设置切片图层的归因信息
              attributions: ['Your Tile Attribution Here']
            })
          }),
        ],
        view: new View({
          center: fromLonLat([112.556197,37.876857]), // 地图中心点坐标(太原市人民政府)
          zoom: 7, // 缩放级别
          maxZoom: 15, // 最大缩放级别
          minZoom: 4.5, // 最小缩放级别
          constrainResolution: true, // 限制分辨率使得地图不会缩得太小
          // extent: transform([73.66, 3.86, 135.05, 53.55],
          //               'EPSG:4326', 'EPSG:3857'),  //中国边界//添加这个范围 经度-最小，纬度-最小，经度-最大，纬度-最大
          // extent: [73.32783475401652, 19.4243521114706, 135.16017906160056, 53.83501005646246],
        }),
      });
      const map = this.map;
      // 监听移动事件
      map.on('moveend', () => {
        var view = map.getView();
        // var extent = view.getProjection().getExtent();
        const defaultPoint = [6379043.021931453, 2085684.0632524858, 17005536.542382672, 7129117.5114353895];
        // // 检查当前视图是否超出了加载的瓦片范围
        if (!this.containsExtent(defaultPoint, view.calculateExtent(map.getSize()))) {
          // 如果超出范围，移回到安全的视图区域
          view.setCenter(fromLonLat([112.556197,37.876857])); // 重新设置中心点
        }
      });
      this.addGeoJson();
    },
    containsExtent(extent1, extent2) {
      return (
        extent1[0] <= extent2[0] &&
        extent2[2] <= extent1[2] &&
        extent1[1] <= extent2[1] &&
        extent2[3] <= extent1[3]
      );
    },
    addGeoJson() {
      let json = require('./taiyuan-1.json');
      let features = (new GeoJSON({ featureProjection: 'EPSG:3857' })).readFeatures(json)
      var vectorSource = new VectorSource({
        features: features
      });
      let lineLayer = new VectorLayer({
          zIndex: 0,
          source: vectorSource,
          // style: this.createStyleFunction()
      });
      this.map.addLayer(lineLayer)  // 把图层添加到地图
    },
    drawKriging() {
      let params={
        mapCenter:[112.555655,37.707188],
        maxValue: 10000,
        krigingModel:'spherical', // 'exponential':指数  'gaussian':高斯,'spherical':球体
        krigingSigma2: 0,
        krigingAlpha: 100,
        canvasAlpha: 0.7, //canvas图层透明度
        colors: this.levelList.map(item => { return item.color })
      };
      // 获取用于显示图例的 <div> 元素
      let legendDiv = document.getElementById('legend-1');
      let legendDiv2 = document.getElementById('legend-2');
        console.log('params.colors: ', params.colors);
      // 遍历 colors 数组，为每个颜色创建一个色块并显示在图例中
      this.levelList.forEach((item,index) => {
          let colorBlock = document.createElement('div');
          colorBlock.style.width = '10px';
          colorBlock.style.height = `${100 / params.colors.length}%`;
          colorBlock.style.backgroundColor = item.color;
          legendDiv.appendChild(colorBlock);
          // if(index % 32 == 0) {
            let colorBlock2 = document.createElement('div');
            colorBlock2.style.textAlign = 'center';
            colorBlock2.innerHTML = `${item.level}<br/>(${item.lower - 0}~${item.upper - 0 || ''})`;
            legendDiv2.appendChild(colorBlock2);
          // }
      });
      let colorBlock2 = document.createElement('div');
      colorBlock2.innerHTML = '';
      legendDiv2.appendChild(colorBlock2);
      //绘制kriging插值图
      let canvasLayer=null;
        // let values=[23,54,11,23,54,11,23,54,11,34,32,11,23,67],
        //   lngs=[112.58,112.58,112.57,112.67,112.45,112.56,112.55,112.58,112.55,116.45,116.45,112.53,112.52,112.58],
        //   lats=[37.86,37.80,37.81,38.06,37.85,37.74,37.97,37.82,37.87,39.89,39.89,37.95,37.85,37.87];
        let values = this.hospitaColorlList.map(item => { return item.indicatrixValue-0 })
        let lngs = this.hospitaColorlList.map(item => { return item.lng - 0 })
        let lats = this.hospitaColorlList.map(item => { return item.lat - 0 })
      // if (values.length>3){
          let variogram=kriging.train(values,lngs,lats,params.krigingModel,params.krigingSigma2,params.krigingAlpha, {radius: 10000});
          let polygons=[...this.bianjie];
          // let clipgeom = new Polygon(this.bianjie)
          // let ex = clipgeom.getExtent()
          let grid=kriging.grid(polygons,variogram,(113-111)/800);
          // let grid=kriging.grid(this.bianjie,variogram,(ex[2]-ex[0])/200);
          //移除已有图层
          if (canvasLayer !== null){
              this.map.removeLayer(canvasLayer);
          }
          //创建新图层
          canvasLayer=new ImageLayer({
            noSwitcherDelete: true,
              source: new ImageCanvas({
                  canvasFunction:(extent, resolution, pixelRatio, size) =>{
                      let canvas = document.createElement('canvas');
                      canvas.width = size[0];
                      canvas.height = size[1];
                      canvas.style.display='block';
                      //设置canvas透明度
                      canvas.getContext('2d').globalAlpha=params.canvasAlpha;
                      //使用分层设色渲染
                      kriging.plot(canvas,grid,[extent[0],extent[2]],[extent[1],extent[3]],[ ...params.colors]);
                      return canvas;
                  },
                  projection: 'EPSG:4326'
              })
          })
          //向map添加图层
          this.map.addLayer(canvasLayer);
      // }else {
      //     alert("有效样点个数不足，无法插值");
      // }

    },
    // 创建一个样式函数，用于设置未差值区域的透明度
    createStyleFunction(value) {
      return function(feature) {
        console.log('feature: ', feature);
        // 获取差值结果
        var z = feature.get('z');
        console.log('z: ', z);
        // 设置透明度
        var alpha = (z === undefined) ? 0.3 : 1.0; // 未差值的透明度
        return new Style({
          fill: new Fill({
            color: 'rgba(255, 0, 0, ' + alpha + ')' // 红色透明度
          }),
          stroke: new Stroke({
            color: 'rgba(0, 0, 0, ' + alpha + ')', // 边界颜色透明度
            width: 1
          })
        });
      };
    }
  },
};
</script>
<style scoped>
.length-box2 {
   height: 180px;
   display: flex;
   flex-direction: column;
   justify-content: space-between;
   align-items: center;
   font-size: 12px;
   margin-left: 4px;
}
.level-box {
  position: fixed;
  right: 24px;
  bottom: 24px;
}
.color-box {
  display: flex;
  align-items: center;
  /* margin-top: 8px; */
  font-size: 14px;
}
.color-div {
  height: 18px;
  width: 24px;
  margin: 0 16px;
}
.search-box {
  position: absolute;
  left: 30px;
  top: 0;
  width: 100%;
  height: 56px;
  padding-left: 16px;
  display: flex;
  align-items: center;
  z-index: 999;
}
</style>
